﻿using UnityEngine;
using System.Collections;
using tcom.tools;

/// <summary>
/// 精灵类型
/// </summary>
public enum SpriteTypeEnum
{
	Hero,									//玩家
	Monster,								//怪物
	Boss,									//Boss
}

/// <summary>
/// 攻击类型
/// </summary>
public enum AttackTypeEnum
{
	Line,									//直线
}

/// <summary>
/// 移动类型
/// </summary>
public enum MoveTypsEnum
{
	Idle,									//空闲状态, 玩家的移动状态
	Y_Axis_Line,							//y 轴直线运动
	Line_Select_Target,						//y 轴选定目标直线运动
	Y_Axis_Line_X_Axis_PingPong,			//y 轴直线运动, x轴 pingpong
	Y_Axis_Stop_Pos,						//y 轴停留在相对位置
	Y_Axis_Stop_X_Axis_PingPong,			//y 轴停留在相对位置, x轴 pingpong
}

/// <summary>
/// 精灵状态
/// </summary>
public enum SpriteStateEnum
{
	Idle,									//空闲状态
	Move,									//移动状态
	Attack,									//攻击状态
	Defense,								//防御状态
	Die,									//死亡状态
	Relive,									//复活状态
}

/// <summary>
/// 精灵类
/// </summary>
public class TSprite : MonoBehaviour {

	[HideInInspector][SerializeField] int hp;							//血
	[HideInInspector][SerializeField] int mp;							//蓝
	[HideInInspector][SerializeField] int attack;						//攻击
	[HideInInspector][SerializeField] int defense;						//防御
	[HideInInspector][SerializeField] float attackFrequency;			//攻击频率
	[HideInInspector][SerializeField] float attackDistance;				//攻击距离
	[HideInInspector][SerializeField] float speedX;						//移动速度 x轴
	[HideInInspector][SerializeField] float speedY;						//移动速度 y轴
	[HideInInspector][SerializeField] int xPingPongLength;				//x 轴pingpong范围			
	[HideInInspector][SerializeField] int yStopPos;						//y 轴停止位置
			
	[HideInInspector][SerializeField] MoveTypsEnum moveType = MoveTypsEnum.Idle;			//精灵的运动状态
	[HideInInspector][SerializeField] AttackTypeEnum attackType = AttackTypeEnum.Line;		//攻击类型
	[HideInInspector][SerializeField] int bulletId;						//精灵使用的子弹id
	
	SpriteStateEnum spriteState = SpriteStateEnum.Idle;	//当前精灵状态
	
	protected ViewRect viewRect;			//视野范围对象
	
	protected Transform target;				//选定的攻击目标
	protected Vector3 moveVector;
	protected Vector3 initVector;			//精灵初始位置
	
	float pingPongTime;						//pingpong阶段时间设置
	
	UISpriteAnimation ani;					//精灵使用的动画
	TTimer attackTimer = new TTimer(1.0f);	//精灵攻击时间控制类
	BulletLevelEnum currBulletLevel = BulletLevelEnum.One;		//当前子弹等级
	
	
	/// <summary>
	/// 初始化函数
	/// </summary>
	public virtual void Init()
	{
		viewRect = ViewRect.GetInstance();
//		target = Thero.GetInstance().transform;
		initVector = transform.localPosition;
		
//		ChangeSpriteState(SpriteStateEnum.Idle);	//设置精灵当前状态为 ilde状态
		
	}
	
	void Start()
	{
		Init();
	}
	
//	void Update()
//	{
//		OnUpdate();
//	}
	
	/// <summary>
	/// 更新函数
	/// </summary>
	public virtual void OnUpdate()
	{
//		SpriteMove();
		
		UpdateSpriteState();
	}
	
	/// <summary>
	/// 更新精灵当前状态信息
	/// </summary>
	public virtual void UpdateSpriteState()
	{
		switch(CurrSpriteState)
		{
		case SpriteStateEnum.Idle:
//			Idle();
			break;
		case SpriteStateEnum.Attack:
//			Attack();
			break;
		case SpriteStateEnum.Defense:
//			Defense();
			break;
		case SpriteStateEnum.Move:
			Move();
			break;
		case SpriteStateEnum.Die:
//			Death();
			break;
		case SpriteStateEnum.Relive:
//			Relive();
			break;
		}
	}
	
	/// <summary>
	/// 改变精灵的状态
	/// </summary>
	public virtual void ChangeSpriteState(SpriteStateEnum state)
	{
		if(CurrSpriteState == state)
			return;
		CurrSpriteState = state;	//改变当前状态
		switch(CurrSpriteState)
		{
		case SpriteStateEnum.Idle:
			Idle();
			break;
		case SpriteStateEnum.Attack:
			Attack();
			break;
		case SpriteStateEnum.Defense:
			Defense();
			break;
		case SpriteStateEnum.Move:
//			Move();					//移动函数在update里面调用
			ChangeMove();
			break;
		case SpriteStateEnum.Die:
			Death();
			break;
		case SpriteStateEnum.Relive:
			Relive();
			break;
		}
	}
	
	/// <summary>
	/// 空闲函数
	/// </summary>
	public virtual void Idle()
	{
		OnChangeSpriteAni(Constant.SPRITE_ANI_IDLE);
	}
	
	/// <summary>
	/// 防御函数
	/// </summary>
	public virtual void Defense()
	{
		OnChangeSpriteAni(Constant.SPRITE_ANI_DEFENSE);	
	}
	
	/// <summary>
	/// 改变为移动状态
	/// </summary>
	public virtual void ChangeMove()
	{
		if(IsHero())
			OnChangeSpriteAni(Constant.SPRITE_ANI_MOVE);
		else
			OnChangeSpriteAni(Constant.SPRITE_ANI_F_MOVE);
	}
	
	/// <summary>
	/// 移动函数
	/// </summary>
	public virtual void Move()
	{
		switch(moveType)
		{
		case MoveTypsEnum.Idle:
			break;
		case MoveTypsEnum.Y_Axis_Line:
			YAxisLine();
			break;
		case MoveTypsEnum.Line_Select_Target:
			LineSelectedTarget();
			break;
		case MoveTypsEnum.Y_Axis_Line_X_Axis_PingPong:
			YAxisLineXAxisPingPong();
			break;
		case MoveTypsEnum.Y_Axis_Stop_Pos:
			YAxisStopPos();
			break;
		case MoveTypsEnum.Y_Axis_Stop_X_Axis_PingPong:
			YAxisStopPosPingPong();
			break;
		default:
			break;
		}
		
		if(!viewRect.IsInViewRect(moveVector))
		{
//			Destroy(gameObject);
			ObjectManager.GetInstance().RemoveObj(gameObject);
		}
		
		CanAttack();
	}
	
	/// <summary>
	/// 死亡函数
	/// </summary>
	public virtual void Death()
	{
		OnChangeSpriteAni(Constant.SPRITE_ANI_DIE);
		
		Debug.LogError(" 精灵死亡 " + gameObject);
		ObjectManager.GetInstance().RemoveObj(gameObject);
	}
	
	/// <summary>
	/// 复活函数
	/// </summary>
	public virtual void Relive()
	{
		OnChangeSpriteAni(Constant.SPRITE_ANI_RELIVE);	
	}
	
	/// <summary>
	/// 攻击函数
	/// </summary>
	public virtual void Attack()
	{
		OnChangeSpriteAni(Constant.SPRITE_ANI_ATTACK);
		
		SetSpriteBullet();
	}
	
	/// <summary>
	/// 根据当前精灵的子弹等级设置子弹
	/// </summary>
	void SetSpriteBullet()
	{
		int count = (int)currBulletLevel;
		for(int i = 0; i < count; i++)
		{
			EffectObj obj = BulletManager.GetFreeEffectObj(BulletId.ToString());
			if(obj == null)
			{
				Debug.LogError("没有子弹 数据");
			}
			else
			{
				obj.obj.SetActive(true);
				TBullet b = obj.obj.GetComponent<TBullet>();
				if(b != null)
				{
					if(IsHero())
					{
						b.Camp = BulletCampEnum.HeroCamp;
						b.transform.localRotation = Quaternion.Euler(Vector3.zero);
					}
					else
					{
						b.Camp = BulletCampEnum.MonCamp;
						b.transform.localRotation = Quaternion.Euler(0, 0, 180);
					}
					b.Obj = obj;
					b.ResetBulletPos(GetPos(), i + 1, count);				
				}
			}
		}
	}
	
	/// <summary>
	/// 检测能否 攻击
	/// </summary>
	void CanAttack()
	{
		attackTimer.Update(Time.deltaTime);
		if(attackTimer.IsReady())
		{
			attackTimer.Reset();
			ChangeSpriteState(SpriteStateEnum.Attack);
		}
	}
	
	/// <summary>
	/// y 轴直线移动
	/// </summary>
	void YAxisLine()
	{
		moveVector = transform.localPosition;
		moveVector.y -= SpeedY;
		
		transform.localPosition += moveVector;
	}
	
	/// <summary>
	/// 选定目标, 移动
	/// </summary>
	void LineSelectedTarget()
	{
		if(target == null || transform.localPosition.y <= target.localPosition.y)	//如果精灵的位置在玩家位置后面则改变精灵的位置为 y轴直线运动
		{
			moveType = MoveTypsEnum.Y_Axis_Line;		
		}
		
		float angle = Vector2.Angle(transform.localPosition, target.localPosition) * Mathf.Deg2Rad;
//		moveVector.x += Mathf.Cos(angle) * SpeedY;
//		moveVector.y -= Mathf.Sin(angle) * SpeedY;
		moveVector.x += Mathf.Sin(angle) * SpeedY;
		moveVector.y -= Mathf.Cos(angle) * SpeedY;
		
		transform.localPosition += moveVector;
	}
	
	/// <summary>
	/// Y 轴直线运动, X轴pingpong 运动
	/// </summary>
	void YAxisLineXAxisPingPong()
	{
		pingPongTime += Time.deltaTime;
		moveVector.x = Mathf.PingPong(pingPongTime * SpeedX, XPingPongLength) + initVector.x;
		moveVector.y = transform.localPosition.y - SpeedY;
		
		transform.localPosition = moveVector;
	}
	
	/// <summary>
	/// y 轴直线运动到固定位置, 然后停止
	/// </summary>
	void YAxisStopPos()
	{
		if(transform.localPosition.y <= YStopPos)
			return;
		
		moveVector = transform.localPosition;
		moveVector.y -= SpeedY;
		
		transform.localPosition = moveVector;
	}
	
	/// <summary>
	/// y 轴直线运动到固定位置, 然后X轴 pingpong
	/// </summary>
	void YAxisStopPosPingPong()
	{
		if(transform.localPosition.y <= YStopPos)
		{
			pingPongTime += Time.deltaTime;
			moveVector.x = Mathf.PingPong(pingPongTime * SpeedX, XPingPongLength) + initVector.x;
			moveVector.y = transform.localPosition.y;
		}
		else
		{
			moveVector = transform.localPosition;
			moveVector.y -= SpeedY;
		}
		
		transform.localPosition = moveVector;
	}
	
	/// <summary>
	/// 精灵图集资源加载完成
	/// </summary>
	public virtual void OnSpriteLoadOverAtals()
	{
		if(AttackFrequency != 0)
			attackTimer.SetTime(AttackFrequency);
		ani = transform.GetComponent<UISpriteAnimation>();
		if(ani)
		{
//			ani.RebuildSpriteList();
//			ani.OnLastFrameCallBack = OnLastFrameCallBack;
			ani.OnLastFrameCallBack = OnLastFrameCallBack;
			ChangeSpriteState(SpriteStateEnum.Move);	//资源图集加载完成之后 改变为移动状态
		}
	}
	
	/// <summary>
	/// 播放到最后一帧
	/// </summary>
	public virtual void OnLastFrameCallBack()
	{
		//攻击动作播放完成之后, 改为移动状态
		
		ChangeSpriteState(SpriteStateEnum.Move);
	}
	
	/// <summary>
	/// 改变精灵的动画序列帧
	/// </summary>
	public void OnChangeSpriteAni(string prefix)
	{
		if(ani == null)
		{
			Debug.LogError("精灵动画为null!" + gameObject + "     " + prefix);
			return;
		}
		
		if(string.Equals(ani.namePrefix, prefix))
		{
			return;
		}
		if(string.Equals(Constant.SPRITE_ANI_ATTACK, prefix))
			ani.loop = false;
		else
			ani.loop = true;
		ani.namePrefix = prefix;
		ani.RebuildSpriteList();
		ani.Reset();
	}
	
	/// <summary>
	/// 判断当前精灵是否是英雄
	/// </summary>
	public bool IsHero()
	{
		return tag.Equals(ObjectManager.TagEnum.Hero.ToString());
	}
	
	/// <summary>
	/// 是否是子弹
	/// </summary>
	public bool IsBullet()
	{
		return tag.Equals(ObjectManager.TagEnum.Bullet.ToString());
	}
	
	/// <summary>
	/// 是否是怪物
	/// </summary>
	public bool IsMonster()
	{
		return tag.Equals(ObjectManager.TagEnum.Monster.ToString());
	}
	
	/// <summary>
	/// 精灵是否可以被攻击
	/// </summary>
	public bool IsCanAttack(BulletCampEnum camp, TSprite sprite)
	{
		bool attack = false;
		if(sprite.IsBullet())
		{
			attack = false;
		}
		else if(camp == BulletCampEnum.HeroCamp)
		{
			if(sprite.IsMonster())
				attack = true;
		}
		else if(camp == BulletCampEnum.MonCamp)
		{
			if(sprite.IsHero())
				attack = true;
		}
		
		return attack;
	}
	
	/// <summary>
	/// 获得精灵的世界坐标
	/// </summary>
	public Vector3 GetPos()
	{
		return transform.position;
	}
	
	/// <summary>
	/// 去除 Z轴的真实距离
	/// </summary>
	public Vector3 GetPosRemoveZ()
	{
		return new Vector3(transform.position.x, transform.position.y, 0);
	}
	
	/// <summary>
	/// 转换 去除 Z 值的位置
	/// </summary>
	public Vector3 GetPosReplaceZ(Vector3 pos, float z)
	{
		return new Vector3(pos.x, pos.y, z);
	}
	
	public int Hp
	{
		get{return hp;}
		set{hp = value;}
	}
	
	public int Mp
	{
		get{return mp;}
		set{mp = value;}
	}
	
	public int AttackValue
	{
		get{return attack;}
		set{attack = value;}
	}
	
	public int DefenseValue
	{
		get{return defense;}
		set{defense = value;}
	}
	
	public float AttackFrequency
	{
		get{return attackFrequency;}
		set{attackFrequency = value;}
	}
	
	public float AttackDistance
	{
		get{return attackDistance;}
		set{attackDistance = value;}
	}
	
	public float SpeedX
	{
		get{return speedX;}
		set{speedX = value;}
	}
	
	public float SpeedY
	{
		get{return speedY;}
		set{speedY = value;}
	}
	
	public int XPingPongLength
	{
		get{return xPingPongLength;}
		set{xPingPongLength = value;}
	}
	
	public int YStopPos
	{
		get{return yStopPos;}
		set{yStopPos = value;}
	}
	
	public int BulletId
	{
		get{return bulletId;}
		set{bulletId = value;}
	}
	
	public AttackTypeEnum AttackType
	{
		get{return attackType;}
		set{attackType = value;}
	}
	
	public MoveTypsEnum MoveType
	{
		get{return moveType;}
		set{moveType = value;}
	}
	
	public SpriteStateEnum CurrSpriteState
	{
		get{return spriteState;}
		set{spriteState = value;}
	}
	
	public Transform Target
	{
		get{return target;}
		set{target = value;}
	}
	
	public BulletLevelEnum CurrBulletLevel
	{
		get{return currBulletLevel;}
		set{currBulletLevel = value;}
	}
}
